package com.jsy.mydbutil;

import android.content.ContentValues;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.text.TextUtils;
import android.util.Log;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;

/**
 * Created by dell on 2017/12/16.
 */

public class MyDbUtil {

    public interface DbGetter{
        MyDataBase getDb();
    }

    static DbGetter dbGetter;
    
    public static void init(DbGetter dbGetter){
        MyDbUtil.dbGetter = dbGetter;
    }
    
    public static String sqliteEscape(String keyWord) {
        return keyWord.replace("/", "//")
                .replace("'", "''")
                .replace("[", "/[")
                .replace("]", "/]")
                .replace("%", "/%")
                .replace("&", "/&")
                .replace("_", "/_")
                .replace("(", "/(")
                .replace(")", "/)");
    }
    


    /**
     * 建表的方法
     *
     * @param tableName  表名称
     * @param tableClass 要建的表对应的实体类
     */
    public static void createTable(Class tableClass, String tableName, SQLiteDatabase db) {
        String sqlString = "CREATE TABLE IF NOT EXISTS  " + tableName + " (";

        //循环获取建表需要的字段：名称，类型，关键字
        // 拿到所有Field
        Field[] declaredFields = tableClass.getDeclaredFields();
        for (Field field : declaredFields) {
            // 获取Field上的注解,只有写了注释的字段才表示要存到表中
            DbProperty dbProperty = field.getAnnotation(DbProperty.class);
            //只有写了注释的字段才表示要存到表中
            if (dbProperty != null) {
                //获取类型
                String type = "TEXT";
                Class fieldClass = field.getType();
                if (fieldClass == int.class || fieldClass == Integer.class || fieldClass == long.class || fieldClass == Long.class) {
                    type = "INTEGER";
                }
                if (field.getType() == float.class || field.getType() == Float.class || field.getType() == double.class || field.getType() == Double.class) {
                    type = "REAL";
                }
                // 获取注解值
                String property = "";
                String[] propertys = dbProperty.property();
                for (String string : propertys) {
                    property += string;
                    property += " ";
                }

                String defaultValue = dbProperty.defaultValue();
                if (!TextUtils.isEmpty(defaultValue)) {
                    defaultValue = " default " + defaultValue + " ";
                }


                //拼接字段名
                sqlString += " " + field.getName();
                //拼接类型
                sqlString += " " + type;
                //拼接关键字
                sqlString += " " + property;
                //拼接默认值
                sqlString += " " + defaultValue;

                sqlString += ",";

            }

        }
        if (sqlString.endsWith(",")) {
            sqlString = sqlString.substring(0, sqlString.length() - 1);
        }
        sqlString += ");";
        Log.e("数据库建表语句:" , sqlString);
        db.execSQL(sqlString);

    }

    public static void createTable(Class tableClass, SQLiteDatabase db) {
        createTable(tableClass, getDefaultTableName(tableClass),db);
    }

    /**
     * 将某个对象插入到某张表
     *
     * @param data
     * @param tableName
     * @return
     * @throws Exception
     */
    public static long insert(String tableName, Object data) throws Exception {
        ContentValues contentValues = new ContentValues();
        Field[] declaredFields = data.getClass().getDeclaredFields();
        for (Field field : declaredFields) {
            // 获取Field上的注解,只有写了注释的字段才表示要存到表中
            DbProperty dbProperty = field.getAnnotation(DbProperty.class);
            //只有写了注释的字段才表示要存到表中
            if (dbProperty != null) {
                //自增长的属性是不用放进去的
                boolean isAutoincrement = false;
                for (String string : dbProperty.property()) {
                    if (string.contains("autoincrement") || string.contains("AUTOINCREMENT")) {
                        isAutoincrement = true;
                    }
                }
                if (!isAutoincrement) {
                    //根据相应类型来获取值，并存入集合
                    Class fieldClass = field.getType();
                    if (fieldClass == String.class) {
                        if ((String) field.get(data)!=null)
                        contentValues.put(field.getName(), (String) field.get(data));
                    } else if (fieldClass == int.class || fieldClass == Integer.class) {
                        contentValues.put(field.getName(), field.getInt(data));
                    } else if (fieldClass == long.class || fieldClass == Long.class) {
                        contentValues.put(field.getName(), field.getLong(data));
                    } else if (fieldClass == float.class || fieldClass == Float.class) {
                        contentValues.put(field.getName(), field.getFloat(data));
                    } else if (fieldClass == double.class || fieldClass == Double.class) {
                        contentValues.put(field.getName(), field.getDouble(data));
                    }
                }

            }
        }

        return dbGetter.getDb().getWritableDatabase().insert(tableName, null, contentValues);
    }
    public static long insert(Object data) throws Exception {
        return insert(getDefaultTableName(data.getClass()),data);
    }


    public static void update(String whereString, String setString, String tableName) {
        dbGetter.getDb().getWritableDatabase().execSQL("update " + tableName+ " set " + setString + " where " + whereString );
    }


    /**
     * 根据 QueryId 修改除自增长以外的所有字段
     * @param data
     * @param tableName
     * @throws Exception
     */
    public static void updateByQueryId(Object data, String tableName) throws Exception {
        String queryId = "";
        ContentValues values = new ContentValues();
        Field[] declaredFields = data.getClass().getDeclaredFields();
        for (Field field : declaredFields) {
            // 获取Field上的注解,只有写了注释的字段才表示要存到表中
            DbProperty dbProperty = field.getAnnotation(DbProperty.class);
            //只有写了注释的字段才表示要存到表中
            if (dbProperty != null) {
                //自增长的属性是不用放进去的
                boolean isAutoincrement = false;
                for (String string : dbProperty.property()) {
                    if (string.contains("autoincrement") || string.contains("AUTOINCREMENT")) {
                        isAutoincrement = true;
                    }
                }
                if (!isAutoincrement) {
                    //根据相应类型来获取值，并存入集合
                    Class fieldClass = field.getType();

                    if (fieldClass == String.class) {
                        values.put(field.getName(), (String) field.get(data));

                    } else if (fieldClass == int.class || fieldClass == Integer.class) {
                        values.put(field.getName(), (Integer) field.get(data));
                    } else if (fieldClass == long.class || fieldClass == Long.class) {
                        values.put(field.getName(), (Long) field.get(data));
                    } else if (fieldClass == float.class || fieldClass == Float.class) {
                        values.put(field.getName(), (Float) field.get(data));
                    } else if (fieldClass == double.class || fieldClass == Double.class) {
                        values.put(field.getName(), (Double) field.get(data));
                    }
                } else {
                    if ("queryId".toLowerCase().equals(field.getName().toLowerCase())) {
                        queryId = (long) field.get(data) + "";
                    }

                }

            }
        }
        dbGetter.getDb().getWritableDatabase().update(tableName, values,"queryId = ?",new String[]{queryId});//execSQL(sql);
    }

    /*public static void update(String whereString, String setString, Class cls) {
        update(whereString,setString,getDefaultTableName(cls));
    }*/

    public static void delete(String tableName, String whereString) {
        dbGetter.getDb().getWritableDatabase().execSQL("delete from " + tableName + " where " + whereString);
    }
    public static void delete(Class tableClass, String whereString) {
        Log.e("要删除的表名：",tableClass.getName()+"==========="+getDefaultTableName(tableClass));
        delete(getDefaultTableName(tableClass),whereString);
    }


    /**
     * @param cls
     * @param whereString //举例： num <  '10000' order by id limit 100;
     * @param tableName
     * @return
     */
    public static <T> List<T> query(Class<T> cls, String whereString, String tableName) {
        ArrayList<T> list = new ArrayList();
        try {
        String sql = "select * from " + tableName;
        if (!TextUtils.isEmpty(whereString)) {
            sql += " where " + whereString;
        }
        //LogUtil.v("查询语句",sql);
        Cursor cursor = dbGetter.getDb().getWritableDatabase().rawQuery(sql, null);
        int count = cursor.getCount();
        if (count == 0) {
            return list;
        } else {
            if (cursor.moveToFirst()) {
                while (true) {
                    T item = cls.newInstance();
                    Field[] declaredFields = item.getClass().getDeclaredFields();
                    for (Field field : declaredFields) {
                        // 获取Field上的注解,只有写了注释的字段才表示要存到表中
                        DbProperty dbProperty = field.getAnnotation(DbProperty.class);
                        //只有写了注释的字段才表示要赋值
                        if (dbProperty != null) {
                            //根据相应类型来获取值，并存入集合
                            Class fieldClass = field.getType();
                            if (fieldClass == String.class) {
                                field.set(item, cursor.getString(cursor.getColumnIndex(field.getName())));
                            } else if (fieldClass == int.class || fieldClass == Integer.class) {
                                field.setInt(item, cursor.getInt(cursor.getColumnIndex(field.getName())));
                            } else if (fieldClass == long.class || fieldClass == Long.class) {
                                field.setLong(item, cursor.getLong(cursor.getColumnIndex(field.getName())));
                            } else if (fieldClass == float.class || fieldClass == Float.class) {
                                field.setFloat(item, cursor.getFloat(cursor.getColumnIndex(field.getName())));
                            } else if (fieldClass == double.class || fieldClass == Double.class) {
                                field.set(item, cursor.getDouble(cursor.getColumnIndex(field.getName())));
                            }
                        }
                    }
                    list.add(item);
                    if (!cursor.moveToNext()) {
                        break;
                    }
                }
            }
            return list;
        }

        }catch (Exception e){
            e.printStackTrace();
            Log.e("查询报错：",e.getMessage());
        }
        return list;
    }

    public static <T> List<T> query(Class<T> cls, String whereString) {
        return query(cls, whereString, getDefaultTableName(cls));
    }

    public static <T> List<T> queryAll(Class<T> cls) {
        return query(cls, "1 == 1", getDefaultTableName(cls));
    }

    public static <T> List<T> queryAll(Class<T> cls,String tableName) {
        return query(cls, "1 == 1", tableName);
    }

    /**
     * 根据默认规则，通过类型获取表名
     * @param c
     * @return
     */
    public static String getDefaultTableName(Class c){
        return c.getName().replaceAll("\\.","_");
    }

}
